 <?php
/**
 * [PHPFOX_HEADER]
 */

defined('PHPFOX') or exit('NO DICE!');

/**
 * PayPal Payment Gateway API
 * 
 * @copyright		[PHPFOX_COPYRIGHT]
 * @author			Fernando Gutierrez
 * @package 		Phpfox
 * @version 		$Id: dwolla.class.php 6851 2013-11-04 16:03:32Z Fernando Gutierrez $
 */
class Phpfox_Gateway_Api_Dwolla implements Phpfox_Gateway_Interface
{
	/**
	 * Holds an ARRAY of settings to pass to the form
	 *
	 * @var array
	 */
	private $_aParam = array();
	
	/**
	 * Holds an ARRAY of supported currencies for this payment gateway
	 *
	 * @var array
	 */
	private $_aCurrency = array('USD');
	
	/**
	 * Class constructor
	 *
	 */
	public function __construct()
	{
		
	}	
	
	/**
	 * Set the settings to be used with this class and prepare them so they are in an array
	 *
	 * @param array $aSetting ARRAY of settings to prepare
	 */
	public function set($aSetting)
	{
		$this->_aParam = $aSetting;
		
		if (Phpfox::getLib('parse.format')->isSerialized($aSetting['setting']))
		{
			$this->_aParam['setting'] = unserialize($aSetting['setting']);
		}
	}
	
	/**
	 * Each gateway has a unique list of params that must be passed with the HTML form when posting it
	 * to their site. This method creates that set of custom fields.
	 *
	 * @return array ARRAY of all the custom params
	 */
	public function getEditForm()
	{		
		return array(
			'dwolla_key' => array(
				'phrase' => Phpfox::getPhrase('dwolla.dwolla_key'),
				'phrase_info' => Phpfox::getPhrase('dwolla.the_dwolla_app_key_provided_when_you_opened_your_account'),
				'value' => (isset($this->_aParam['setting']['dwolla_key']) ? $this->_aParam['setting']['dwolla_key'] : '')
			),
			'dwolla_secret' => array(
				'phrase' => Phpfox::getPhrase('dwolla.dwolla_secret'),
				'phrase_info' => Phpfox::getPhrase('dwolla.the_dwolla_secret_provided_when_you_opened_your_account'),
				'value' => (isset($this->_aParam['setting']['dwolla_secret']) ? $this->_aParam['setting']['dwolla_secret'] : '')
			),
			'dwolla_id' => array(
				'phrase' => Phpfox::getPhrase('dwolla.dwolla_id'),
				'phrase_info' => Phpfox::getPhrase('dwolla.the_dwolla_id_provided_when_you_opened_your_account'),
				'value' => (isset($this->_aParam['setting']['dwolla_id']) ? $this->_aParam['setting']['dwolla_id'] : '')
			)
		);
	}
	
	/**
	 * Returns the actual HTML <form> used to post information to the 3rd party gateway when purchasing
	 * an item using this specific payment gateway
	 *
	 * @return bool FALSE if we can't use this payment gateway to purchase this item or ARRAY if we have successfully created a form
	 */
	public function getForm()
	{		
		$bCurrencySupported = true;
				
		if (!in_array($this->_aParam['currency_code'], $this->_aCurrency))
		{
			if (!empty($this->_aParam['alternative_cost']))
			{
				$aCosts = unserialize($this->_aParam['alternative_cost']);
				foreach ($aCosts as $aCost)
				{
					$sCode = key($aCost);
					$iPrice = $aCost[key($aCost)];
					
					if (in_array($sCode, $this->_aCurrency))
					{
						$this->_aParam['amount'] = $iPrice;
						$this->_aParam['currency_code'] = $sCode;
						$bCurrencySupported = false;
						break;
					}
				}
			   
				if ($bCurrencySupported === true)
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
		
		$aForm = array(
			'url' => 'https://www.dwolla.com/payment/pay/',
			'param' => array(
				'key' => $this->_aParam['setting']['dwolla_key'],
				'secret' => $this->_aParam['setting']['dwolla_secret'],
				'timestamp' => PHPFOX_TIME,
				'callback' => Phpfox::getLib('gateway')->url('dwolla'),
				'redirect' => $this->_aParam['return'],
				'allowFundingSources' => 'true',
				'orderId' => $this->_aParam['item_number'],
				'test' => ($this->_aParam['is_test'] ? 'true' : 'false'),
				'destinationId' => $this->_aParam['setting']['dwolla_id'],
				'amount' => $this->_aParam['amount'],
				'shipping' => 0,
				'tax' => 0,
				'name' => $this->_aParam['item_name'],
				'description' => $this->_aParam['item_name'] . ' ' . $this->_aParam['item_number']
			)
		);
		
		$aForm['param']['signature'] = hash_hmac(
				'sha1', 
				"{" . $aForm['param']['key'] . "}&{" . $aForm['param']['timestamp'] . "}&{" . $aForm['param']['orderId'] . "}",
				$this->_aParam['setting']['dwolla_secret']
		);
		
		
		if ($this->_aParam['recurring'] > 0)
		{
			// Dwolla does not support recurring payments through the form.
			// http://help.dwolla.com/customer/portal/articles/1181832-recurring-payments
			$sError = 
				'<div class="row1">
					<div class="gateway_title">Dwolla</div>
					<div class="extra_info">
						' . Phpfox::getPhrase('dwolla.recurring_not_supported') . '
					</div>
				</div>
				<div class="p_4 t_right"></div>';
			
			Phpfox_Error::display($sError);
			return false;
		}
		
		return $aForm;
	}
	
	/**
	 * Performs the callback routine when the 3rd party payment gateway sends back a request to the server,
	 * which we must then back and verify that it is a valid request. This then connects to a specific module
	 * based on the information passed when posting the form to the server.
	 *
	 */
	public function callback()
	{
		Phpfox::log('Starting Dwolla callback');
		// get the response
		$aMessage = json_decode(file_get_contents('php://input'), true);
		// logging details		
		Phpfox::log('Attempting callback');
		// Did dwolla return something?
		if(!empty($aMessage))
		{
			// So far, everything goes well
			Phpfox::log('Callback OK');
			// get the PHPFox module
			$aParts = explode('|', $aMessage['OrderId']);
			Phpfox::log('Attempting to load module: ' . $aParts[0]);
			// Is valid module?
			if (Phpfox::isModule($aParts[0]))
			{
				Phpfox::log('Module ' . $aParts[0] . ' is valid');
				Phpfox::log('Checking module callback for method: paymentApiCallback');
				if (Phpfox::hasCallback($aParts[0], 'paymentApiCallback'))
				{
					Phpfox::log('Building payment status: ' . (isset($aMessage['Status']) ? strtolower($aMessage['Status']) : 'null'));
					// build status
					$sStatus = null;				
					if (isset($aMessage['Status']))
					{
						// Check the variables sent back by Dwolla
						switch(strtolower($aMessage['Status']))
						{
							case 'completed':
								$sStatus = 'completed';
								break;
							case 'failed':
								$sStatus = 'cancel';
								break;
							default:
								// should not enter here!
								$sStatus = 'pending';
								break;
						}
						Phpfox::log('Status built: ' . $sStatus);
						// Status not null, report to module callback
						if ($sStatus !== null)
						{
							Phpfox::log('Executing module callback');
							Phpfox::callback($aParts[0] . '.paymentApiCallback', array(
									'gateway' => 'dwolla',
									'ref' => $aMessage['TransactionId'],
									'invoice' => $aMessage['CheckoutId'],
									'status' => $sStatus,
									'item_number' => $aParts[1],
									'total_paid' => $aMessage['Amount']
								)
							);
							// send 200 OK! :D
							header('HTTP/1.1 200 OK');				
						}

					}
					else 
					{
						Phpfox::log('Status is NULL. Nothing to do');
					}
				}
				else 
				{
					Phpfox::log('Module callback is not valid');
				}
			}
			else 
			{
				Phpfox::log('Module is not valid.');
			}
		}
		else
		{
			Phpfox::log('Callback FAILED');
		}
	}
}

?>
